package org.jiangwei.cmput696.entitylinking;

import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * The class contains information of a referenced document.
 * 
 * @author jiangwei
 * 
 */
public class ELQueriedDocument {

	public static final String SPECIAL_STR = "[SPECIAL_STR]";

	private String docPath;

	private String text;

	private List<String> paragraphs;

	private String title;

	private String docType;

	private String dateStr;

	private String surface;

	private String rawText;

	/**
	 * The begin offset in text.
	 */
	private int begin;

	/**
	 * The end offset in text.
	 */
	private int end;

	public ELQueriedDocument(String docPath, int oriBegin, int oriEnd)
			throws QueryParsingException {
		this.docPath = docPath;

		rawText = Helper.getRawText(new File(docPath));
		surface = rawText.substring(oriBegin, oriEnd);
		
//		System.out.println(oriBegin + ", " + oriEnd);
//		System.out.println(rawText.substring(oriBegin, oriEnd));

		String replaced = rawText.substring(0, oriBegin) + SPECIAL_STR
				+ rawText.substring(oriEnd);
		parseDoc(replaced);

//		System.out.println(rawText.substring(oriBegin, oriEnd));
//		System.out.println(text);

		// replace the surface in text
		begin = text.indexOf(SPECIAL_STR);
		end = begin + oriEnd - oriBegin;
		
//		System.out.println(begin + ", " + end);
		
//		text = replaced.substring(0, begin) + surface
//				+ text.substring(begin + SPECIAL_STR.length());
		
//		System.out.println(text.substring(begin, end));
	}


	private void parseDoc(String xmlString) throws QueryParsingException {
		DocumentBuilder db = Helper.createDocumentBuilder();
		Document doc = null;
		try {
			doc = db.parse(new InputSource(new StringReader(xmlString)));
		} catch (SAXException e) {
			throw new QueryParsingException("Failed to parse source document.",
					e);
		} catch (IOException e) {
			throw new QueryParsingException("Source document not found.", e);
		}

		title = retrieveElementText(doc, "HEADLINE");
		docType = retrieveElementText(doc, "DOCTYPE");
		dateStr = retrieveElementText(doc, "DATETIME");

		StringBuilder sb = new StringBuilder();
		paragraphs = new ArrayList<String>();
		// make the title a part of the text
		sb.append(title);
		paragraphs.add(title);

		NodeList pList = doc.getElementsByTagName("TEXT");
		for (int i = 0; i < pList.getLength(); i++) {
			String temp = pList.item(i).getTextContent();
//			String temp = retrieveElementText((Element) pList.item(i));
			paragraphs.add(temp.trim());
			sb.append(temp);
		}

		text = sb.toString();
	}

	private static Node retrieveNode(Document doc, String name) {
		NodeList list = doc.getElementsByTagName(name);
		if (list == null || list.getLength() == 0)
			return null;
		return (Node) list.item(0);
	}

	private static String retrieveElementText(Document doc, String name) {
		Element element = (Element) retrieveNode(doc, name);
		return retrieveElementText(element);
	}

	private static String retrieveElementText(Element element) {
		if (element == null) return null;
		NodeList nodeList = element.getChildNodes();
		if (nodeList == null || nodeList.getLength() == 0)
			return null;
		return nodeList.item(0).getTextContent();
	}

	public String getDocPath() {
		return docPath;
	}

	public String getText() {
		return text;
	}

	public String getTitle() {
		return title;
	}

	public String getDocType() {
		return docType;
	}

	public String getDateStr() {
		return dateStr;
	}

	public List<String> getParagraphs() {
		return paragraphs;
	}

	public String getSurface() {
		return surface;
	}

	public String getRawText() {
		return rawText;
	}

	public int getBegin() {
		return begin;
	}

	public int getEnd() {
		return end;
	}

}
